<?php
// +----------------------------------------------------------------------
// | Bwsaas
// +----------------------------------------------------------------------
// | Copyright (c) 2015~2020 http://www.buwangyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Gitee ( https://gitee.com/buwangyun/bwsaas )
// +----------------------------------------------------------------------
// | Author: buwangyun <hnlg666@163.com>
// +----------------------------------------------------------------------
// | Date: 2020-9-28 10:55:00
// +----------------------------------------------------------------------

namespace app\manage\model\admin;

use app\common\model\member\Wallet;
use buwang\base\TimeModel;
use app\manage\model\AuthGroup;
use app\common\model\Miniapp;
use app\manage\model\Member;
use app\common\model\MemberMiniapp;
use app\common\model\MemberMiniappOrder;

class MiniappModule extends TimeModel
{
    protected $deleteTime = false;


    // 追加属性
    protected $append = [
        'price_list',
    ];


    public function getPriceListAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['price_json']) ? $data['price_json'] : '');
        if(!$value)return [];
        //解析json串
        $list = json_decode($data['price_json'], true);//数组转json
        if(!$list)return [];

        // 总平台配置的套餐规格扩展字段.
        $packageExtendFields = self::getAppMealSpecExtendFieldApi($this->miniapp_id);
        if (!empty($packageExtendFields)) {
            foreach ($list as &$item) {
                $extendFields = [];
                foreach ($packageExtendFields as $packageExtendField) {
                    if (isset($item[ $packageExtendField['key'] ])) {
                        $extendFields[] = [
                            'name'  => $packageExtendField['value'],
                            'value' => $item[ $packageExtendField['key'] ],
                        ];
                    }
                }

                $item['extendPackageFields'] = $extendFields;
            }
        }

        //按权重排序
        //根据权重字段last_name对数组$data进行降序排列
        $weights = array_column($list,'weight');
        array_multisort($weights,SORT_DESC,$list);
        return $list;
    }

    public function getTypeList()
    {
        return ['1' => '基础功能', '2' => '附加功能'];
    }



    /**得到套餐角色树
     * @param $dir
     * @param $where
     * @param int $pid
     * @param array $checked_ids
     * @param bool $disabled
     * @param bool $is_child
     * @param null $self
     */
    public static function getAppRoles($dir,$id=0,$pid = 0, $disabled = true, $is_child = false){
        if(is_numeric($dir))$dir = Miniapp::where('id',$dir)->value('dir');
        $checked_ids = [];
        $where=[];
        $where['scopes'] = 'member';
        $where['app_name'] = $dir;
        $where['type'] = 'app';
        $where['member_id'] = 0;
        //查询套餐已拥有的角色
        if($id){
            $self = self::where('id',$id)->find();
            if($self){
                if($self['group_id']) $checked_ids = explode(',',$self['group_id']);
            }
        }

        return  AuthGroup::getTree($where, $pid, $checked_ids, $disabled, $is_child);
    }

    /**
     * 得到套餐角色树[用于API接口]
     * @param $dir
     * @param int $id
     * @param int $pid
     * @return array
     */
    public static function getAppRolesApi($dir,int $id=0, int $pid = 0): array
    {
        if(is_numeric($dir)) $dir = Miniapp::where('id',$dir)->value('dir');
        $where=[];
        $checked_ids=[];
        $where['scopes'] = 'member';
        $where['app_name'] = $dir;
        $where['type'] = 'app';
        $where['member_id'] = 0;
        //查询套餐已拥有的角色
        if($id){
            $self = self::where('id',$id)->find();
            if($self){
                if($self['group_id']) $checked_ids = explode(',',$self['group_id']);
            }
        }
        return  AuthGroup::getAppMeal($where,$checked_ids, $pid);
    }


    /**
     * 获取总平台配置的套餐规格的扩展字段.
     *
     * @param mixed $dir
     *
     * @return array|mixed
     */
    public static function getAppMealSpecExtendFieldApi($dir) {
        if (is_numeric($dir)) {
            $dir = Miniapp::where('id', $dir)
                ->value('dir');
        }
        if (empty($dir)) {
            return [];
        }
        $package_extends = bw_config(sprintf('%s_config.package_extend', $dir), '', null, $dir);

        if (empty($package_extends)) {
            return [];
        }

        $package_extends = json_decode($package_extends, true);
        if (empty($package_extends)) {
            return [];
        }

        return $package_extends;
    }

//    /**
//     * 价格查询
//     */
//    public static function priceFind($id,$price_id){
//        $self = self::where('id',$id)->find();
//        if(!$self||!$self['price_list'])return [];
//        $price_list = $self['price_list'];
//        //返回查找到的第一个结果
//        $rs = array_filter($price_list, function($t) use ($price_id) {
//            if(!isset($t['id']))return false;
//            return $t['id'] == $price_id;
//        });
//        //为查找到
//        if(!$rs) return [];
//        $rs = array_values($rs);
//        return $rs[0];
//    }

    /**
     * 查找套餐规格.
     *
     * @param     $id
     * @param  $price_id
     *
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function priceFind($id, $price_id):array {
        $self = self::where('id', $id)
            ->find();
        if (empty($self) || empty($self['price_list'])) {
            return [];
        }

        foreach ($self['price_list'] as $item) {
            if (!isset($item['uuid'])) {
                continue;
            }

            if ($item['uuid'] == $price_id) {
                return $item;
            }
        }

        return [];
    }




    /** 应用续费（通过售卖套餐）
     * @param $param
     * @param bool $trans
     * @return bool
     * @throws \Exception
     */
    public function renew($id,$price_id,$password,$member_id,$trans=false){ //id套餐id  price_id价格规格id   password 支付密码  member_id租户id
        //查询套餐
        $self = self::where('id',$id)->find();
        if(!$self) throw new \Exception('未找到充值套餐');
        //得到充值套餐
        $price_info = self::priceFind($id,$price_id);
        //TODO 新版本采用了索引值来获取套餐规格信息
        if(!$price_info && isset($self['price_list'][$price_id])){
            $price_info=$self['price_list'][$price_id];
        }
        if(!$price_info) throw new \Exception('未找到套餐规格');
        if (!$password) throw new \Exception('请填写支付密码');
        $user = Member::where('id',$member_id)->find();
        if(!$user)throw new \Exception('租户不存在');
        //提交支付
        if (!Member::checkPassword($password, $user['safe_password'])) throw new \Exception('支付密码错误');
        $memberMiniapp = MemberMiniapp::where('member_id',$member_id)->where('miniapp_id',$self['miniapp_id'])->find();
        if(!$memberMiniapp) throw new \Exception('未购买该应用,不可续费');
        if($memberMiniapp['expire_time'] ==0)throw new \Exception('已永久拥有，无需再续费购买');
        //应用信息
        $miniapp = Miniapp::where('id',$self['miniapp_id'])->find();
        if(!$miniapp)throw new \Exception('找不到该应用');
        if($trans){
            self::startTrans();
        }
        $time = time();
        //如果应用还未过期，用剩余时间累加
        $memberMiniappOrder = MemberMiniappOrder::where('member_id',$memberMiniapp['member_id'])->where('miniapp_id',$memberMiniapp['miniapp_id'])->where('miniapp_module_id',$id)->order('create_time desc')->find();
        if($memberMiniappOrder&&$memberMiniappOrder['expire_time']>$time)$time = $memberMiniappOrder['expire_time'];
        try{
            $days = $price_info['day']==0 ? '到永久':$price_info['day'].'天';
            //扣费
            //TODO 余额判断
            $user_money=Wallet::where(['member_id' => $member_id])->lock(true)->value('money');
            if($price_info['price']>$user_money) throw new \Exception('您余额不足，请先充值');

            $fee =\app\common\model\member\Wallet::changeMoney($member_id, 'miniapp', 0 - $price_info['price'], "应用【{$miniapp['title']}】续费{$days}");
            if(!$fee) throw new \Exception(\app\common\model\member\Wallet::getError());
            //增加应用购买订单记录
            $orderParam = [
                'member_id' => $member_id,        //租户id
                'miniapp_id' => $self['miniapp_id'], //应用id
                'miniapp_module_id' => $self['id'], //模块id
                'title' => $miniapp['title'],   //应用名
                'update_var' => 0,              //小程序模板ID 0
                'price' => $price_info['price'],    //模块价格
                'valid_days' => $price_info['day'], //有效天数
                'expire_time' => $price_info['day'] > 0 ? $time + $price_info['day'] * 24 * 60 * 60 : 0, //过期时间
                'miniapp_module_type' => 1, //得到功能类型
            ];
            $memberMiniappOrder = MemberMiniappOrder::create($orderParam);

            //更新租户应用时长
            $memberMiniapp['expire_time'] =  $price_info['day'] > 0 ? $time + $price_info['day'] * 24 * 60 * 60 : 0;
            //TODO 更新租户应用订单id【用来记录最近的一次购买】
            $memberMiniapp['miniapp_order_id'] = $memberMiniappOrder['id'];
            $memberMiniapp->save();
        }catch (\Exception $e){
            if($trans){
                self::rollback();
            }
            throw new \Exception($e->getMessage());
        }
        return true;
    }

    public static function haveBuy($member_id,$id){
        //判断是购买还是续费，如果是续费调用续费方法
        $module = MiniappModule::where('id',$id)->find();
        if (!$module) throw new \Exception('该套餐信息不存在！');
        $memberMiniapp = MemberMiniapp::where('member_id',$member_id)->where('miniapp_id',$module['miniapp_id'])->find();
        //未购买应用可以买
        if(!$memberMiniapp) return true;
        $memberMiniappOrder = MemberMiniappOrder::where('id',$memberMiniapp['miniapp_order_id'])->find();
        if(!$memberMiniappOrder) throw new \Exception('租户套餐订单数据异常');
        //应用买的最新套餐
        $memberMiniappOrder = MemberMiniappOrder::where('member_id',$member_id)
            ->where('miniapp_id',$module['miniapp_id'])
            ->where('miniapp_module_id',$module['id'])
            ->find();
        //买了其他套餐可以买当前套餐
        if(!$memberMiniappOrder) return true;
        //否则只能续费
        return false;

    }



}